var apiFormat = "https://api.vk.com/method/{0}";

function time(seconds) {
	var h = Math.floor(seconds / 3600);
	var m = Math.floor(seconds % 3600 / 60);
	var s = Math.floor(seconds % 3600 % 60);
	return ((h > 0 ? h + ":" : "") + (m > 0 ? (h > 0 && m < 10 ? "0" : "") + m + ":" : "0:") + (s < 10 ? "0" : "") + s);
}

function untime(time) {
	var components = time.split(':').reverse();
	var seconds = 0;
	var k = [1, 60, 3600];
	for (var i = 0; i < components.length; i++) seconds += components[i] * k[i];
	return seconds;
}

var tracksToSearch;
var tracksToSearchArtists;
var tracksFinded;

function searchNextTracks(callback) {
	if (tracksToSearch.length) {
		var code = "";
		for (var i = 0; i < 5 && i < tracksToSearch.length; i++) {
			code += Ext.String.format('API.audio.search({"q":"{0}","count":20}),', tracksToSearch[i].artist + " - " + tracksToSearch[i].title);
		}
		code = "return [" + code + "];";
		Ext.Ajax.request({
			method: "get",
		    url: Ext.String.format(apiFormat, "execute"),
		    params: {
		    	access_token: localStorage.token,
		    	code: code
		    },
		    success: function(response, opts) {
		    	var items = Ext.decode(response.responseText).response;
		    	for (var j = 0; j < items.length && j + tracksFinded < ssTracklistStore.data.items.length; j++) {
		    		var record = tracksToSearch[j].record;
			    	var closest = 1;
			    	var dur = record.get("duration");
			    	for (var i = 2; i < items[j].length && dur != 0; i++) {
			    		if (Math.abs(items[j][i].duration - dur) < Math.abs(items[j][closest].duration - dur)) closest = i;
			    	}
					if (items[j][closest]) {
						record.set("aid", items[j][closest].aid);
						record.set("owner_id", items[j][closest].owner_id);
						record.set("url", items[j][closest].url);
						record.set("duration", time(items[j][closest].duration));
						record.set("name", record.get('title'));
						record.set("artist", tracksToSearchArtists);
					} else record.unfined = true;
			    }
			    tracksFinded += items.length;
			    tracksToSearch.splice(0, items.length);
			    setTimeout(function() {searchNextTracks(callback)}, 1000);
		    },
		    failure: function(response, opts) {
		    	setTimeout(function() {searchNextTracks(callback)}, 1000);
		    }
		});
	} else {
		callback(true);
	}
}

function vksearch(callback) {
	tracksToSearch = [];
	tracksFinded = 0;
	tracksToSearchArtists = "";
	for (var i in release.get("artists")) {
		tracksToSearchArtists += release.get("artists")[i].name + ((i == release.get("artists").length - 1)?"":", ");
	}
	ssTracklistStore.each(function(record) {
		tracksToSearch.push({artist: tracksToSearchArtists, title: record.get('title'), record: record});
	});
	searchNextTracks(callback);
}

Ext.Loader.setConfig({enabled: true});
Ext.require([
	'Ext.panel.*',
	'Ext.toolbar.*',
	'Ext.button.*',
	'Ext.container.ButtonGroup',
	'Ext.layout.container.Table'
]);

var ssWindow;
var ssReleasesStore;
var ssReleasesSearchStore;
var ssArtistsSearchStore;
var ssTracklistStore;
var artistsView;
var albumsView;
var release;

Ext.onReady(function() {
	Ext.define('Artist', {
	    extend: 'Ext.data.Model',
	    fields: [
	        { name:'name', type:'string' },
	        { name:'releases_url', type:'string' },
	        { name:'name', type:'string' },
	        { name:'uri', type:'string' },
	        { name:'members', type:'array' },
	        { name:'urls', type:'array' },
	        { name:'images', type:'array' },
	        { name:'resource_url', type:'string' },
	        { name:'id', type:'integer' },
	    	{ name:'data_quality', type:'string' },
	    	{ name:'namevariations', type:'array' }
		]
	});

	Ext.define('SearchResult', {
	    extend: 'Ext.data.Model',
	    fields: [
	        { name:'thumb', type:'string' },
	        { name:'title', type:'string' },
	        { name:'uri', type:'string' },
	        { name:'resource_url', type:'string' },
	        { name:'type', type:'string' },
	        { name:'id', type:'integer' }
		]
	});

	Ext.define('Release', {
	    extend: 'Ext.data.Model',
	    fields: [
	    	{ name:'status', type:'string' },
	        { name:'thumb', type:'string' },
	        { name:'title', type:'string' },
	        { name:'main_release', type:'integer' },
	        { name:'format', type:'string' },
	        { name:'label', type:'string' },
	        { name:'role', type:'string' },
	        { name:'year', type:'integer' },
	        { name:'resource_url', type:'string' },
	        { name:'type', type:'string' },
	        { name:'id', type:'integer' }
		]
	});

	Ext.define('Track', {
	    extend: 'Ext.data.Model',
	    fields: [
	    	{ name:'duration', type:'string', convert: function(v, record) {
	    		return untime(v);
	    	}},
	        { name:'position', type:'string' },
	        { name:'title', type:'string' }
		]
	});

	Ext.define('ReleaseDetails', {
	    extend: 'Ext.data.Model',
	    fields: [
	    	{ name:'styles', type:'array' },
	        { name:'series', type:'array' },
	        { name:'labels', type:'array' },
	        { name:'year', type:'integer' },
	        { name:'artists', type:'array' },
	        { name:'images', type:'array' },
	        { name:'id', type:'integer' },
	        { name:'genres', type:'array' },
	        { name:'thumb', type:'string' },
	        { name:'extraartists', type:'array' },
	        { name:'title', type:'string' },
	        { name:'tracklist', type:'array' },
	        { name:'status', type:'string' },
	        { name:'released_formatted', type:'string' },
	        { name:'released', type:'string' },
	        { name:'country', type:'string' },
	        { name:'notes', type:'string' },
	        { name:'companies', type:'array' },
	        { name:'uri', type:'string' },
	        { name:'formats', type:'array' },
	        { name:'resource_url', type:'string' },
	        { name:'data_quality', type:'string' }
		]
	});

	SearchStore = Ext.extend(Ext.data.Store, {
	    constructor: function(config) {
	        Ext.apply(this, {
	        	model: 'SearchResult',
	        	pageSize: 25,
			    proxy: {
			        type: 'ajax',
			        url: 'http://api.discogs.com/database/search',
			        extraParams: {
			        	per_page: 25,
			        	q: config.q,
			        	type: config.type
			        },
			        reader: {
			            type: 'json',
			            root: 'results',
			            totalProperty: 'pagination.items'
			        }
			    }
	            
	        });
	        SearchStore.superclass.constructor.apply(this, arguments);
	    }
	});

	ReleasesStore = Ext.extend(Ext.data.Store, {
	    constructor: function(config) {
	        Ext.apply(this, {
	        	model: 'Release',
			    proxy: {
			        type: 'ajax',
			        url: Ext.String.format('http://api.discogs.com/artists/{0}/releases', config.artistid),
			        reader: {
			            type: 'json',
			            root: 'releases'
			        }
			    }
	            
	        });
	        SearchStore.superclass.constructor.apply(this, arguments);
	    }
	});
	ssReleasesStore = new ReleasesStore({artistid: 0});
	ssReleasesSearchStore = new SearchStore({
		type: 'release',
		listeners: {
			load: function(store, records) {
				store.each(function(record) {
					record.set('thumb', record.get('thumb').replace('-90-', '-150-'));
				});
				ssReleasesStore.loadRecords(records);
			}
		}
	});
	ssArtistsSearchStore = new SearchStore({
		type: 'artist',
		listeners: {
			load: function(store, records) {
				store.each(function(record) {
					record.set('thumb', record.get('thumb').replace('-90-', '-150-'));
				});
			}
		}
	});
	ssTracklistStore = Ext.create('Ext.data.Store', {model: 'Track'});
	artistsView = Ext.create('Ext.view.View', {
        store: ssArtistsSearchStore,
        tpl: [
            '<tpl for=".">',
                '<div class="thumb-wrap" id="{id}">',
                '<div class="thumb"><div style="background:url({thumb}) no-repeat center center; height: 150px; width: 150px;"></div></div>',
                '<span>{title}</span></div>',
            '</tpl>',
            '<div class="x-clear"></div>'
        ],
        trackOver: true,
        overItemCls: 'x-item-over',
        itemSelector: 'div.thumb-wrap',
        emptyText: 'Исполнители по данному критерию не найдены или произошла ошибка',
        listeners: {
        	itemdblclick: function(view, record) {
        		Ext.getCmp('tabpanel').setActiveTab('albums');
        		ssReleasesStore.proxy.url = Ext.String.format('http://api.discogs.com/artists/{0}/releases', record.get("id"));
        		ssReleasesStore.load();
        	}
        }
    });

	albumsView = Ext.create('Ext.view.View', {
        store: ssReleasesStore,
        tpl: [
            '<tpl for=".">',
                '<div class="thumb-wrap" id="{id}">',
                '<div class="thumb"><div style="background:url({thumb}) no-repeat center center; height: 150px; width: 150px;"></div></div>',
                '<span>{title}</span></div>',
            '</tpl>',
            '<div class="x-clear"></div>'
        ],
        trackOver: true,
        overItemCls: 'x-item-over',
        itemSelector: 'div.thumb-wrap',
        emptyText: 'Альбомы по данному критерию не найдены или произошла ошибка',
        listeners: {
        	itemdblclick: function(view, record) {
        		Ext.getCmp('tabpanel').setActiveTab('album');
        		Ext.getCmp('albumimage').setSrc('images/noavatar.jpg');
        		Ext.getCmp('albumimage').imageN = 0;
        		Ext.getCmp('albumimage').images = ['images/noavatar.jpg'];
        		ssTracklistStore.removeAll();
				Ext.getCmp('albumdesc').setText("");
				Ext.Ajax.request({
				    url: Ext.String.format('http://api.discogs.com/releases/{0}', record.get("id")),
				    method: 'get',
				    success: function(response){
				    	var obj = Ext.decode(response.responseText);
				        for (var i = 0; i < obj.tracklist.length; i++)
				        	if (!obj.tracklist[i].position || /(DVD)|(VIDEO)/gi.test(obj.tracklist[i].position)) obj.tracklist.splice(i--, 1);
				        release = new ReleaseDetails(obj);
						ssTracklistStore.loadData(release.get("tracklist"));
						var images = [];
						for (var i in release.get('images')) {
							images[i] = release.get('images')[i].uri;
						}
						Ext.getCmp('albumimage').images = images;
						Ext.getCmp('albumimage').imageN = 0;
						Ext.getCmp('albumimage').setSrc(images[0]);
				    }
				});
        	}
        }
    });

	ssWindow = new Ext.window.Window({
	    title: 'Умный поиск',
	    layout: 'card',
	    modal: true,
	    closeAction: 'hide',
	    constrain: true,
	    maximized: true,
	    resizable: false,
	    items: Ext.create('Ext.tab.Panel', {
	    	id: 'tabpanel',
			activeTab: 'artists',
		    items: [
			    {
			    	id: 'artists',
			        title: 'Исполнители',
			        autoScroll: true,
					tbar: {
					        xtype: 'pagingtoolbar',
					        afterPageText: ' из {0}',
					        beforePageText: 'Страница',
					        firstText: 'Первая страница',
					        lastText: 'Последняя страница',
					        nextText: 'Следующая страница',
					        prevText: 'Предыдущая страница',
					        refreshText: 'Обновить',
					        store: ssArtistsSearchStore,
					        items: [
					        	{
					        		xtype: 'textfield',
					        		emptyText: 'Имя исполнителя',
					        		value: 'hillsong',
									listeners: {
										specialkey: function(field, e) {
											if (e.getKey() == e.ENTER) {
												ssArtistsSearchStore.proxy.extraParams.q = this.value;
												ssArtistsSearchStore.load();
											}
										}
									}
					        	}
					        ]
					},
			        items: [
				    	artistsView
			        ]
			    },
			    {
			    	id: 'albums',
			        title: 'Альбомы',
			        autoScroll: true,
					tbar: {
					        xtype: 'pagingtoolbar',
					        afterPageText: ' из {0}',
					        beforePageText: 'Страница',
					        firstText: 'Первая страница',
					        lastText: 'Последняя страница',
					        nextText: 'Следующая страница',
					        prevText: 'Предыдущая страница',
					        refreshText: 'Обновить',
					        store: ssReleasesSearchStore,
					        items: [
					        	{
					        		xtype: 'textfield',
					        		emptyText: 'Название альбома',
									listeners: {
										specialkey: function(field, e) {
											if (e.getKey() == e.ENTER) {
												ssReleasesSearchStore.proxy.extraParams.q = this.value;
												ssReleasesSearchStore.load();
											}
										}
									}
					        	}
					        ]
					},
			        items: [
				    	albumsView
			        ]
			    },
			    {
					id: 'album',
			        title: 'Альбом',
					layout: 'border',
					items: [
						{
							region: 'west',
							split: true,
							width: 220,
							collapsible: true,
							preventHeader: true,
							title: 'Описание альбома',
							items: [
								{
									id: 'albumimage',
									xtype: 'image',
									src: 'images/noavatar.jpg',
									imageN: 0,
									images: ['images/noavatar.jpg'],
									width: 218
								},
								{
									xtype: 'button',
									text: '←',
									handler: function() {
										var image = Ext.getCmp('albumimage');
										image.setSrc(image.images[(--image.imageN + image.images.length) % image.images.length]);
									}
								},
								{
									xtype: 'button',
									text: '→',
									handler: function() {
										var image = Ext.getCmp('albumimage');
										image.setSrc(image.images[++image.imageN % image.images.length]);
									}
								},
								{
									id: 'albumdesc',
									xtype: 'label'
								}
							],
							listeners: {
								resize: function(imagepanel, adjWidth, adjHeight, eOpts) {
									Ext.getCmp('albumimage').setWidth(adjWidth - 2);
								}
							}
						},
						{
							xtype: 'grid',
							region: 'center',
							autoScroll: true,
							store: ssTracklistStore,
							bbar: [
								'->',
								{
									text: 'Очистить плейлист',
									handler: function() {
										localStorage.playlistType = "albumSMART";
										store.removeAll();
										chrome.extension.getBackgroundPage().bg.playlist = [];
										needReact = false;
										Ext.getCmp("myaudio").toggle(false);
										Ext.getCmp("recommendedaudio").toggle(false);
										Ext.getCmp("popularaudio").toggle(false);
										Ext.getCmp("searchaudio").toggle(false);
										Ext.getCmp("albumaudio").toggle(true);
										needReact = true;
									}
								},
								{
									text: 'Добавить в плейлист',
									handler: function() {
										var myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Поиск аудиозаписей вконтакте…"});
										myMask.show();
										vksearch(function() {
											myMask.hide();
											if (localStorage.playlistType != "albumSMART") {
												localStorage.playlistType = "albumSMART";
												store.removeAll();
												chrome.extension.getBackgroundPage().bg.playlist = ssTracklistStore.data.items;
												needReact = false;
												Ext.getCmp("myaudio").toggle(false);
												Ext.getCmp("recommendedaudio").toggle(false);
												Ext.getCmp("popularaudio").toggle(false);
												Ext.getCmp("searchaudio").toggle(false);
												Ext.getCmp("albumaudio").toggle(true);
												needReact = true;
												store.loadRecords(ssTracklistStore.data.items);
											} else {
												chrome.extension.getBackgroundPage().bg.playlist = chrome.extension.getBackgroundPage().bg.playlist.concat(ssTracklistStore.data.items);
												store.loadRecords(ssTracklistStore.data.items, {addRecords: true});
											}
										});
									}
								}
							],
							columns: [
								{
									xtype: 'rownumberer',
									align: 'right',
									width: 30
								},
								{
									header: 'Композиция',
									dataIndex: 'title',
									menuDisabled: true,
									resizable: false,
									flex: 1
								},
								{
									header: 'Время',
									dataIndex: 'duration',
									renderer: function(value) {
										return time(value);
									},
									align: 'center',
									width: 60,
									resizable: false,
									menuDisabled: true,
									sortable: false
								}
							]
						}
					]
			    }
		    ]
		})
	});
});